//
//  PlayingViewController.swift
//  QQMusic
//
//  Created by hjj on 2016/12/3.
//  Copyright © 2016年 hjjuny. All rights reserved.
//

import UIKit
import AVFoundation
import MediaPlayer

class PlayingViewController: UIViewController {
    
    // MARK: 控件属性
    @IBOutlet weak var bgImageView: UIImageView!
    @IBOutlet weak var progressSlider: UISlider!
    @IBOutlet weak var iconImageView: UIImageView!
    @IBOutlet weak var songLabel: UILabel!
    @IBOutlet weak var singerLabel: UILabel!
    @IBOutlet weak var currentTimeLabel: UILabel!
    @IBOutlet weak var totalTimeLabel: UILabel!
    @IBOutlet weak var lrcScrollView: LrcScrollView!
    @IBOutlet weak var lrcLabel: LrcLabel!
    @IBOutlet weak var playOrPauseBtn: UIButton!
    
    @IBOutlet weak var iconViewWCons: NSLayoutConstraint!
    
    // MARK: 懒加载属性
    fileprivate lazy var musics : [MusicModel] = [MusicModel]()
    fileprivate var progressTimer : Timer?
    fileprivate var lrcTimer : CADisplayLink?
    fileprivate var currentMusic : MusicModel!
    
    // MARK: 系统回调
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // 1.设置UI界面
        setupUI()
        
        // 2.加载数据
        loadMusicData()
        
        // 3.播放歌曲
        currentMusic = musics[2]
        startPlayingMusic()
    }
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        
        lrcScrollView.setTableViewContentOffset()
    }
}


// MARK:- 设置UI界面
extension PlayingViewController {
    fileprivate func setupUI() {
        // 1.设置毛玻璃的View
        setupBlurView()
        
        // 2.设置UISlider的滑块图片
        progressSlider.setThumbImage(UIImage(named: "player_slider_playback_thumb"), for: .normal)
        
        // 3.设置IconImageView的圆角
        setupIconViewCons()
        
        // 4.设置UIScrollView的contentSize
        lrcScrollView.contentSize = CGSize(width: view.bounds.width * 2, height: 0)
        lrcScrollView.lrcDelegate = self
    }
    
    private func setupBlurView() {
        let blurEffect = UIBlurEffect(style: .dark)
        let blurView = UIVisualEffectView(effect: blurEffect)
        blurView.frame = CGRect(x: 0, y: 0, width: 414, height: 667)
        blurView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
        bgImageView.addSubview(blurView)
    }
    
    private func setupIconViewCons() {
        
        var ratio : CGFloat = 0.7
        if UIScreen.main.bounds.height == 480 {
            ratio = 0.6
        }
        let kScreenW = UIScreen.main.bounds.width
        iconViewWCons.constant = kScreenW * ratio - kScreenW
        
        iconImageView.layer.cornerRadius = view.bounds.width * ratio * 0.5
        iconImageView.layer.masksToBounds = true
        iconImageView.layer.borderWidth = 8
        iconImageView.layer.borderColor = UIColor.black.cgColor
    }
    
    override var preferredStatusBarStyle: UIStatusBarStyle {
        return .lightContent
    }
}


// MARK:- 加载歌曲数据
extension PlayingViewController {
    fileprivate func loadMusicData() {
        // 1.获取plist文件的路径
        guard let plistPath = Bundle.main.path(forResource: "Musics.plist", ofType: nil) else { return }
        
        // 2.读取plist文件中数据
        guard let dataArray = NSArray(contentsOfFile: plistPath) as? [[String : Any]] else { return }
        
        // 3.字典转模型
        for dict in dataArray {
            musics.append(MusicModel(dict: dict))
        }
    }
}


// MARK:- 播放歌曲
extension PlayingViewController {
    fileprivate func startPlayingMusic() {
        // 0.播放当前歌曲
        MusicTools.playMusic(currentMusic.filename)
        MusicTools.setPlayerDelegate(self)
        
        // 1.改变界面中的内容
        bgImageView.image = UIImage(named: currentMusic.icon)
        iconImageView.image = UIImage(named: currentMusic.icon)
        songLabel.text = currentMusic.name
        singerLabel.text = currentMusic.singer
        progressSlider.value = 0
        
        // 2.修改显示的时间
        currentTimeLabel.text = "00:00"
        totalTimeLabel.text = stringWithTime(MusicTools.getDuration())
        
        // 3.添加更新进度的定时器
        removeProgressTimer()
        addProgressTimer()
        
        // 4.给IconImageView添加动画
        addRotationAnim()
        
        // 5.将歌词文件的名称传入到UIScrollView中
        lrcScrollView.lrcname = currentMusic.lrcname
        
        // 6.添加更新歌词的定时器
        removeLrcTimer()
        addLrcTimer()
        
        // 7.更新锁屏界面的信息
        setupLockInfo(image: UIImage(named: currentMusic.icon))
    }
    
    fileprivate func stringWithTime(_ time : TimeInterval) -> String {
        let min = Int(time) / 60
        let second = Int(time) % 60
        
        return String(format: "%02d:%02d", min, second)
    }
    
    fileprivate func addRotationAnim() {
        // 1.创建动画(CABasic/KeyFrame)
        let rotationAnim = CABasicAnimation(keyPath: "transform.rotation.z")
        
        // 2.设置动画的属性
        rotationAnim.fromValue = 0
        rotationAnim.toValue = M_PI * 2
        rotationAnim.repeatCount = MAXFLOAT
        rotationAnim.duration = 30
        
        rotationAnim.isRemovedOnCompletion = false
        
        // 3.将动画添加到layer中
        iconImageView.layer.add(rotationAnim, forKey: nil)
    }
}


// MARK:- 对歌曲进度的控制
extension PlayingViewController {
    @IBAction func sliderTouchDown() {
        removeProgressTimer()
    }
    
    @IBAction func sliderValueChange() {
        // 1.获取当前进度对应的时间
        let time = Double(progressSlider.value) * MusicTools.getDuration()
        
        // 2.将时间显示在CurrentTimeLabel中
        currentTimeLabel.text = stringWithTime(time)
    }
    
    @IBAction func sliderTouchUpInside() {
        updateCurrentTime()
    }
    
    @IBAction func sliderTouchUpOutside() {
        updateCurrentTime()
    }
    
    private func updateCurrentTime() {
        // 1.获取当前进度对应的时间
        let time = Double(progressSlider.value) * MusicTools.getDuration()
        
        // 2.将当前播放时间设置成该时间
        MusicTools.setCurrentTime(time)
        
        // 3.将定时器添加进来
        addProgressTimer()
    }
    
    @IBAction func sliderTapGes(_ sender: UITapGestureRecognizer) {
        // 1.获取手指点击的位置
        let point = sender.location(in: progressSlider)
        
        // 2.计算该位置x对应的比例
        let ratio = point.x / progressSlider.bounds.width
        
        // 3.根据比例,改变歌曲的进度
        let time = Double(ratio) * MusicTools.getDuration()
        MusicTools.setCurrentTime(time)
        updateProgress()
    }
}


// MARK:- 对定时器的操作
extension PlayingViewController {
    fileprivate func addProgressTimer() {
        progressTimer = Timer(timeInterval: 1.0, target: self, selector: #selector(updateProgress), userInfo: nil, repeats: true)
        RunLoop.main.add(progressTimer!, forMode: .commonModes)
    }
    
    fileprivate func removeProgressTimer() {
        progressTimer?.invalidate()
        progressTimer = nil
    }
    
    @objc fileprivate func updateProgress() {
        currentTimeLabel.text = stringWithTime(MusicTools.getCurrentTime())
        progressSlider.value = Float(MusicTools.getCurrentTime() / MusicTools.getDuration())
    }
    
    
    fileprivate func addLrcTimer() {
        lrcTimer = CADisplayLink(target: self, selector: #selector(updateLrc))
        lrcTimer?.add(to: RunLoop.main, forMode: .commonModes)
    }
    
    fileprivate func removeLrcTimer() {
        lrcTimer?.invalidate()
        lrcTimer = nil
    }
    
    @objc fileprivate func updateLrc() {
        lrcScrollView.currentTime = MusicTools.getCurrentTime()
    }
}


// MARK:- 更新歌曲(上一首/下一首/暂停/播放)
extension PlayingViewController {
    @IBAction func previousMusic() {
        switchMusic(isNext: false)
    }
    
    @IBAction func nextMusic() {
        switchMusic(isNext: true)
    }
    
    private func switchMusic(isNext : Bool) {
        
        // 1.根据当前的歌曲,获取下标值
        let currentIndex = musics.index(of: currentMusic)!
        
        // 2.获取下一首歌曲的下标值
        var index : Int = 0
        if isNext {
            index = currentIndex + 1
            // index = index > musics.count - 1 ? 0 : index
            if index > musics.count - 1 {
                index = 0
            }
        } else {
            index = currentIndex - 1
            // index = index < 0 ? musics.count - 1 : index
            if index < 0 {
                index = musics.count - 1
            }
        }
       
        // 3.根据下标值取出歌曲
        currentMusic = musics[index]
        
        // 4.播放该歌曲
        startPlayingMusic()
    }
    
    @IBAction func playOrPauseMusic(btn : UIButton) {
        // 1.改变按钮的状态
        btn.isSelected = !btn.isSelected
        
        // 2.根据状态,播放&暂停歌曲
        if btn.isSelected {
            MusicTools.playMusic(currentMusic.filename)
            iconImageView.layer.resumeAnim()
        } else {
            MusicTools.pauseMusic()
            iconImageView.layer.pauseAnim()
        }
    }
}


// MARK:- UIScrollView的代理
extension PlayingViewController : UIScrollViewDelegate, LrcScrollViewDelegate {
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        let ratio = scrollView.contentOffset.x / scrollView.bounds.width
        iconImageView.alpha = 1 - ratio
        lrcLabel.alpha = 1 - ratio
    }
    
    func lrcScrollView(_ lrcScrollView: LrcScrollView, lrcText: String, progress: Double) {
        lrcLabel.text = lrcText
        lrcLabel.progress = progress
    }
    
    func lrcScrollView(_ lrcScrollView: LrcScrollView, _ nextLrcText: String, _ currentLrcText: String, _ preLrcText: String) {
        // 1.获取封面图片
        guard let image = UIImage(named: currentMusic.icon) else { return }
        
        // 2.根据图片尺寸,开启上下文
        UIGraphicsBeginImageContextWithOptions(image.size, true, 0.0)
        
        // 3.先将图片画到上下文
        image.draw(in: CGRect(origin: CGPoint.zero, size: image.size))
        
        // 4.定义一些常量
        let textH : CGFloat = 30
        
        // 4.画出下一句歌词
        let nextRect = CGRect(x: 0, y: image.size.height - textH, width: image.size.width, height: textH)
        let style = NSMutableParagraphStyle()
        style.alignment = .center
        let nextAttrs = [NSForegroundColorAttributeName : UIColor.white, NSFontAttributeName : UIFont.systemFont(ofSize: 15), NSParagraphStyleAttributeName : style]
        (nextLrcText as NSString).draw(in: nextRect, withAttributes: nextAttrs)
        
        // 5.画出当前句歌词
        let currentRect = CGRect(x: 0, y: image.size.height - 2 * textH, width: image.size.width, height: textH)
        let currentAttrs = [NSForegroundColorAttributeName : UIColor.green, NSFontAttributeName : UIFont.systemFont(ofSize: 16), NSParagraphStyleAttributeName : style]
        (currentLrcText as NSString).draw(in: currentRect, withAttributes: currentAttrs)
        
        // 6.画出上一句歌词
        let preRect = CGRect(x: 0, y: image.size.height - 3 * textH, width: image.size.width, height: textH)
        (preLrcText as NSString).draw(in: preRect, withAttributes: nextAttrs)
        
        // 7.从上下文中获取图片
        let lrcImage = UIGraphicsGetImageFromCurrentImageContext()
        
        // 8.关闭上下文
        UIGraphicsEndImageContext()
        
        // 9.根据最新图片,设置锁屏界面的信息
        setupLockInfo(image: lrcImage)
    }
}


// MARK:- 监听歌曲播放完成
extension PlayingViewController : AVAudioPlayerDelegate {
    func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
        if flag {
            nextMusic()
        }
    }
}


// MARK:- 设置锁屏界面的信息
/*
 // MPMediaItemPropertyAlbumTitle
 // MPMediaItemPropertyAlbumTrackCount
 // MPMediaItemPropertyAlbumTrackNumber
 // MPMediaItemPropertyArtist
 // MPMediaItemPropertyArtwork
 // MPMediaItemPropertyComposer
 // MPMediaItemPropertyDiscCount
 // MPMediaItemPropertyDiscNumber
 // MPMediaItemPropertyGenre
 // MPMediaItemPropertyPersistentID
 // MPMediaItemPropertyPlaybackDuration
 // MPMediaItemPropertyTitle
 */
extension PlayingViewController {
    func setupLockInfo(image : UIImage?) {
        // 1.获取锁屏中心
        let centerInfo = MPNowPlayingInfoCenter.default()
        
        // 2.设置信息
        var infoDict = [String : Any]()
        infoDict[MPMediaItemPropertyAlbumTitle] = currentMusic.name
        infoDict[MPMediaItemPropertyArtist] = currentMusic.singer
        if let image = image {
            infoDict[MPMediaItemPropertyArtwork] = MPMediaItemArtwork(image: image)
        }
        
        infoDict[MPMediaItemPropertyPlaybackDuration] = MusicTools.getDuration()
        centerInfo.nowPlayingInfo = infoDict
        
        // 3.让应用程序成为第一响应者
        UIApplication.shared.becomeFirstResponder()
        UIApplication.shared.beginReceivingRemoteControlEvents()
    }
    
    override func remoteControlReceived(with event: UIEvent?) {
        // 1.校验远程事件是否有值
        guard let event = event else {
            return
        }
        
        // 2.处理远程事件
        switch event.subtype {
        case .remoteControlPlay, .remoteControlPause:
            playOrPauseMusic(btn: playOrPauseBtn)
        case .remoteControlNextTrack:
            nextMusic()
        case .remoteControlPreviousTrack:
            previousMusic()
        default:
            print("-----")
        }
    }
}



